package qw

import (
	"encoding/json"
	"errors"
	"log/slog"
	"net/url"
)

// ListExternalContact 获取客户列表
// 企业可通过此接口获取指定成员添加的客户列表。客户是指配置了客户联系功能的成员所添加的外部联系人。没有配置客户联系功能的成员，所添加的外部联系人将不会作为客户返回。
func (w *QYWXApi) ListExternalContact(userId string) ([]string, error) {
	accessToken, err := w.GetAccessToken()
	if err != nil {
		return nil, err
	}

	var values = url.Values{}
	values.Add("access_token", accessToken)
	values.Add("userid", userId)

	reqUrl := "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list?" + values.Encode()

	// 调试
	//url += "&debug=1"

	res, err := w.getHttpSvc().HttpGet(reqUrl, nil)
	if err != nil {
		slog.Error(err.Error())
		return nil, err
	}

	// 调试日志
	slog.Debug("ListExternalContact", "response", string(res.Body))

	type Result struct {
		Errcode        int      `json:"errcode"`
		Errmsg         string   `json:"errmsg"`
		ExternalUserid []string `json:"external_userid"`
	}

	var result Result
	if err := json.Unmarshal(res.Body, &result); err != nil {
		slog.Error(err.Error())
		return nil, err
	}
	if result.Errcode != 0 {
		return nil, errors.New("获取客户列表，返回结果：" + string(res.Body))
	}
	return result.ExternalUserid, nil
}

// GetExternalContact 获取客户详情
// 企业可通过此接口，根据外部联系人的userid（如何获取?），拉取客户详情。
func (w *QYWXApi) GetExternalContact(externalUserId, cursor string) (*ExternalContactDetailResult, error) {
	accessToken, err := w.GetAccessToken()
	if err != nil {
		return nil, err
	}

	var values = url.Values{}
	values.Add("access_token", accessToken)
	values.Add("external_userid", externalUserId)
	if len(cursor) > 0 {
		values.Add("cursor", cursor)
	}
	reqUrl := "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get?" + values.Encode()

	// 调试
	//url += "&debug=1"

	res, err := w.getHttpSvc().HttpGet(reqUrl, nil)
	if err != nil {
		slog.Error(err.Error())
		return nil, err
	}

	// 调试日志
	slog.Debug("GetExternalContact", "response", string(res.Body))

	var result ExternalContactDetailResult
	if err := json.Unmarshal(res.Body, &result); err != nil {
		slog.Error(err.Error())
		return nil, err
	}
	if result.Errcode != 0 {
		return nil, errors.New("获取客户详情，返回结果：" + string(res.Body))
	}
	return &result, nil
}

// ConvertExternalContactUserIdToOpenId 转换openid(通过微信外部联系人userid)
// 企业和服务商可通过此接口，将微信外部联系人的userid（如何获取?）转为微信openid，用于调用支付相关接口
// 暂不支持企业微信外部联系人（ExternalUserid为wo开头）的userid转openid。
func (w *QYWXApi) ConvertExternalContactUserIdToOpenId(externalUserId string) (string, error) {
	accessToken, err := w.GetAccessToken()
	if err != nil {
		return "", err
	}

	var values = url.Values{}
	values.Add("access_token", accessToken)
	reqUrl := "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/convert_to_openid?" + values.Encode()

	// 调试
	//url += "&debug=1"

	var param = map[string]any{
		"external_userid": externalUserId,
	}
	data, _ := json.Marshal(param)

	res, err := w.getHttpSvc().HttpPost(reqUrl, nil, data)
	if err != nil {
		slog.Error(err.Error())
		return "", err
	}

	// 调试日志
	slog.Debug("ConvertExternalContactUserIdToOpenId", "response", string(res.Body))

	type Result struct {
		Errcode int    `json:"errcode"`
		Errmsg  string `json:"errmsg"`
		OpenId  string `json:"openid"`
	}

	var result Result
	if err := json.Unmarshal(res.Body, &result); err != nil {
		slog.Error(err.Error())
		return "", err
	}
	if result.Errcode != 0 {
		return "", errors.New("转换openid失败，返回结果：" + string(res.Body))
	}
	return result.OpenId, nil
}

// GetUserBehaviorData 获取「联系客户统计」数据
// 企业可通过此接口获取成员联系客户的数据，包括发起申请数、新增客户数、聊天数、发送消息数和删除/拉黑成员的客户数等指标。
func (w *QYWXApi) GetUserBehaviorData(userId string, startTime int64, endTime int64) ([]UserBehaviorData, error) {
	accessToken, err := w.GetAccessToken()
	if err != nil {
		return nil, err
	}

	var values = url.Values{}
	values.Add("access_token", accessToken)
	reqUrl := "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_user_behavior_data?" + values.Encode()

	var param = map[string]any{
		"userid":     []string{userId},
		"start_time": startTime,
		"end_time":   endTime,
	}
	data, _ := json.Marshal(param)

	res, err := w.getHttpSvc().HttpPost(reqUrl, nil, data)
	if err != nil {
		slog.Error(err.Error())
		return nil, err
	}

	// 调试日志
	slog.Debug("GetUserBehaviorData", "response", string(res.Body))

	type Result struct {
		Errcode      int                `json:"errcode"`
		Errmsg       string             `json:"errmsg"`
		BehaviorData []UserBehaviorData `json:"behavior_data"`
	}
	var result Result
	if err := json.Unmarshal(res.Body, &result); err != nil {
		slog.Error(err.Error())
		return nil, err
	}
	if result.Errcode != 0 {
		return nil, errors.New("获取「联系客户统计」数据失败，返回结果：" + string(res.Body))
	}
	return result.BehaviorData, nil
}

// TransferCustomer1 分配在职成员的客户
// 企业可通过此接口，转接在职成员的客户给其他成员。
func (w *QYWXApi) TransferCustomer1(fromUserId string, toUserId string, externalUserIdList []string, msg string) ([]TransferCustomerResult, error) {
	accessToken, err := w.GetAccessToken()
	if err != nil {
		return nil, err
	}

	var values = url.Values{}
	values.Add("access_token", accessToken)
	reqUrl := "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/transfer_customer?" + values.Encode()

	var param = map[string]any{
		"handover_userid":      fromUserId,
		"takeover_userid":      toUserId,
		"external_userid":      externalUserIdList,
		"transfer_success_msg": msg,
	}
	data, _ := json.Marshal(param)

	res, err := w.getHttpSvc().HttpPost(reqUrl, nil, data)
	if err != nil {
		slog.Error(err.Error())
		return nil, err
	}

	// 调试日志
	slog.Debug("TransferCustomer1", "response", string(res.Body))

	type Result struct {
		Errcode  int                      `json:"errcode"`
		Errmsg   string                   `json:"errmsg"`
		Customer []TransferCustomerResult `json:"customer"`
	}

	var result Result
	if err := json.Unmarshal(res.Body, &result); err != nil {
		slog.Error(err.Error())
		return nil, err
	}
	if len(result.Customer) == 0 {
		return nil, errors.New("转移客户失败")
	}
	return result.Customer, nil
}

// TransferResult1 查询客户接替状态
// 企业和第三方可通过此接口查询在职成员的客户转接情况。
func (w *QYWXApi) TransferResult1(fromUserId string, toUserId string, cursor string) ([]TransferCustomerResult, string, error) {
	accessToken, err := w.GetAccessToken()
	if err != nil {
		return nil, "", err
	}

	var values = url.Values{}
	values.Add("access_token", accessToken)
	reqUrl := "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/transfer_result?" + values.Encode()

	var param = map[string]any{
		"handover_userid": fromUserId,
		"takeover_userid": toUserId,
		"cursor":          cursor,
	}
	data, _ := json.Marshal(param)

	res, err := w.getHttpSvc().HttpPost(reqUrl, nil, data)
	if err != nil {
		slog.Error(err.Error())
		return nil, "", err
	}

	// 调试日志
	slog.Debug("TransferResult1", "response", string(res.Body))

	type Result struct {
		Errcode    int                      `json:"errcode"`
		Errmsg     string                   `json:"errmsg"`
		Customer   []TransferCustomerResult `json:"customer"`
		NextCursor string                   `json:"next_cursor"`
	}

	var result Result
	if err := json.Unmarshal(res.Body, &result); err != nil {
		slog.Error(err.Error())
		return nil, "", err
	}
	if len(result.Customer) == 0 {
		return nil, "", errors.New("转移客户失败")
	}
	return result.Customer, result.NextCursor, nil
}

// TransferCustomer2 分配离职成员的客户
// 企业可通过此接口，转接离职成员的客户给其他成员。
func (w *QYWXApi) TransferCustomer2(fromUserId string, toUserId string, externalUserIdList []string) ([]TransferCustomerResult, error) {
	accessToken, err := w.GetAccessToken()
	if err != nil {
		return nil, err
	}

	var values = url.Values{}
	values.Add("access_token", accessToken)
	reqUrl := "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/resigned/transfer_customer?" + values.Encode()

	var param = map[string]any{
		"handover_userid": fromUserId,
		"takeover_userid": toUserId,
		"external_userid": externalUserIdList,
	}
	data, _ := json.Marshal(param)

	res, err := w.getHttpSvc().HttpPost(reqUrl, nil, data)
	if err != nil {
		slog.Error(err.Error())
		return nil, err
	}

	// 调试日志
	slog.Debug("TransferCustomer2", "response", string(res.Body))

	type Result struct {
		Errcode  int                      `json:"errcode"`
		Errmsg   string                   `json:"errmsg"`
		Customer []TransferCustomerResult `json:"customer"`
	}

	var result Result
	if err := json.Unmarshal(res.Body, &result); err != nil {
		slog.Error(err.Error())
		return nil, err
	}
	if result.Errcode != 0 {
		return nil, errors.New("转移客户失败，返回结果：" + string(res.Body))
	}
	return result.Customer, nil
}

// TransferResult2 查询客户接替状态
// 企业和第三方可通过此接口查询离职成员的客户转接情况。
func (w *QYWXApi) TransferResult2(fromUserId string, toUserId string, cursor string) ([]TransferCustomerResult, string, error) {
	accessToken, err := w.GetAccessToken()
	if err != nil {
		return nil, "", err
	}

	var values = url.Values{}
	values.Add("access_token", accessToken)
	reqUrl := "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/resigned/transfer_result?" + values.Encode()

	var param = map[string]any{
		"handover_userid": fromUserId,
		"takeover_userid": toUserId,
		"cursor":          cursor,
	}
	data, _ := json.Marshal(param)

	res, err := w.getHttpSvc().HttpPost(reqUrl, nil, data)
	if err != nil {
		slog.Error(err.Error())
		return nil, "", err
	}

	// 调试日志
	slog.Debug("TransferResult2", "response", string(res.Body))

	type Result struct {
		Errcode    int                      `json:"errcode"`
		Errmsg     string                   `json:"errmsg"`
		Customer   []TransferCustomerResult `json:"customer"`
		NextCursor string                   `json:"next_cursor"`
	}

	var result Result
	if err := json.Unmarshal(res.Body, &result); err != nil {
		slog.Error(err.Error())
		return nil, "", err
	}
	if result.Errcode != 0 {
		return nil, "", errors.New("转移客户失败，返回结果：" + string(res.Body))
	}
	return result.Customer, result.NextCursor, nil
}

// SendWelcomeMsg 发送新客户欢迎语
func (w *QYWXApi) SendWelcomeMsg(welcomeCode string, text string, link string, title string, content string, picUrl string) error {
	accessToken, err := w.GetAccessToken()
	if err != nil {
		return err
	}

	var values = url.Values{}
	values.Add("access_token", accessToken)
	reqUrl := "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/send_welcome_msg?" + values.Encode()

	var param = map[string]any{
		"welcome_code": welcomeCode,
		"text": map[string]any{
			"content": text,
		},
		"attachments": []map[string]any{
			{
				"msgtype": "link",
				"link": map[string]any{
					"title":  title,
					"desc":   content,
					"url":    link,
					"picurl": picUrl,
				},
			},
		},
	}
	data, _ := json.Marshal(param)

	res, err := w.getHttpSvc().HttpPost(reqUrl, nil, data)
	if err != nil {
		slog.Error(err.Error())
		return err
	}

	// 调试日志
	slog.Debug("SendWelcomeMsg", "response", string(res.Body))

	type Result struct {
		Errcode int    `json:"errcode"`
		Errmsg  string `json:"errmsg"`
	}

	var result Result
	if err := json.Unmarshal(res.Body, &result); err != nil {
		slog.Error(err.Error())
		return err
	}
	if result.Errcode != 0 {
		return errors.New("发送新客户欢迎语失败，返回结果：" + string(res.Body))
	}
	return nil
}

// UpdateCustomerRemark 更新企微客户备注
func (w *QYWXApi) UpdateCustomerRemark(userId, externalUserId, remark string, mobiles []string) error {
	accessToken, err := w.GetAccessToken()
	if err != nil {
		return err
	}

	var values = url.Values{}
	values.Add("access_token", accessToken)
	reqUrl := "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/remark?" + values.Encode()

	var param = map[string]any{
		"userid":          userId,
		"external_userid": externalUserId,
		"remark":          remark,
	}
	if len(mobiles) > 0 {
		param["remark_mobiles"] = mobiles
	}
	data, _ := json.Marshal(param)

	res, err := w.getHttpSvc().HttpPost(reqUrl, nil, data)
	if err != nil {
		slog.Error(err.Error())
		return err
	}

	// 调试日志
	slog.Debug("UpdateCustomerRemark", "response", string(res.Body))

	type Result struct {
		Errcode int    `json:"errcode"`
		Errmsg  string `json:"errmsg"`
	}

	var result Result
	if err := json.Unmarshal(res.Body, &result); err != nil {
		slog.Error(err.Error())
		return err
	}
	if result.Errcode != 0 {
		return errors.New("更新客户备注失败，返回结果：" + string(res.Body))
	}
	return nil
}

// UpdateCustomerTags 更新企微客户备注
func (w *QYWXApi) UpdateCustomerTags(userId, externalUserId string, addTagIds []string, removeTagIds []string) error {
	accessToken, err := w.GetAccessToken()
	if err != nil {
		return err
	}

	var values = url.Values{}
	values.Add("access_token", accessToken)
	reqUrl := "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/mark_tag?" + values.Encode()

	var param = map[string]any{
		"userid":          userId,
		"external_userid": externalUserId,
		"add_tag":         addTagIds,
		"remove_tag":      removeTagIds,
	}
	data, _ := json.Marshal(param)

	res, err := w.getHttpSvc().HttpPost(reqUrl, nil, data)
	if err != nil {
		slog.Error(err.Error())
		return err
	}

	// 调试日志
	slog.Debug("UpdateCustomerTags", "response", string(res.Body))

	type Result struct {
		Errcode int    `json:"errcode"`
		Errmsg  string `json:"errmsg"`
	}

	var result Result
	if err := json.Unmarshal(res.Body, &result); err != nil {
		slog.Error(err.Error())
		return err
	}
	if result.Errcode != 0 {
		return errors.New("更新客户备注失败，返回结果：" + string(res.Body))
	}
	return nil
}

// GetCorpTagList 获取企业标签库
func (w *QYWXApi) GetCorpTagList() ([]TagGroup, error) {
	accessToken, err := w.GetAccessToken()
	if err != nil {
		return nil, err
	}

	var values = url.Values{}
	values.Add("access_token", accessToken)
	reqUrl := "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get_corp_tag_list?" + values.Encode()

	var param = map[string]any{}
	data, _ := json.Marshal(param)

	res, err := w.getHttpSvc().HttpPost(reqUrl, nil, data)
	if err != nil {
		slog.Error(err.Error())
		return nil, err
	}

	// 调试日志
	slog.Debug("GetCorpTagList", "response", string(res.Body))

	type Result struct {
		Errcode  int        `json:"errcode"`
		Errmsg   string     `json:"errmsg"`
		TagGroup []TagGroup `json:"tag_group"`
	}

	var result Result
	if err := json.Unmarshal(res.Body, &result); err != nil {
		slog.Error(err.Error())
		return nil, err
	}
	if result.Errcode != 0 {
		return nil, errors.New("更新客户备注失败，返回结果：" + string(res.Body))
	}
	return result.TagGroup, nil
}

// AddCorpTag 添加企业标签
func (w *QYWXApi) AddCorpTag(groupName, tagName string, sortWeight int, agentId int64) (*TagGroup, error) {
	accessToken, err := w.GetAccessToken()
	if err != nil {
		return nil, err
	}

	var values = url.Values{}
	values.Add("access_token", accessToken)
	reqUrl := "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/add_corp_tag?" + values.Encode()

	var param = map[string]any{
		"group_name": groupName,
		"tag": []map[string]any{
			{
				"name":  tagName,
				"order": sortWeight,
			},
		},
		"agentid": agentId,
	}
	data, _ := json.Marshal(param)

	res, err := w.getHttpSvc().HttpPost(reqUrl, nil, data)
	if err != nil {
		slog.Error(err.Error())
		return nil, err
	}

	// 调试日志
	slog.Debug("AddCorpTag", "response", string(res.Body))

	type Result struct {
		Errcode  int      `json:"errcode"`
		Errmsg   string   `json:"errmsg"`
		TagGroup TagGroup `json:"tag_group"`
	}

	var result Result
	if err := json.Unmarshal(res.Body, &result); err != nil {
		slog.Error(err.Error())
		return nil, err
	}
	if result.Errcode != 0 {
		return nil, errors.New("添加企业标签，返回结果：" + string(res.Body))
	}
	return &result.TagGroup, nil
}

// EditCorpTag 编辑企业标签
func (w *QYWXApi) EditCorpTag(tagId, tagName string, sortWeight int, agentId int64) error {
	accessToken, err := w.GetAccessToken()
	if err != nil {
		return err
	}

	var values = url.Values{}
	values.Add("access_token", accessToken)
	reqUrl := "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/edit_corp_tag?" + values.Encode()

	var param = map[string]any{
		"id":      tagId,
		"name":    tagName,
		"order":   sortWeight,
		"agentid": agentId,
	}
	data, _ := json.Marshal(param)

	res, err := w.getHttpSvc().HttpPost(reqUrl, nil, data)
	if err != nil {
		slog.Error(err.Error())
		return err
	}

	// 调试日志
	slog.Debug("EditCorpTag", "response", string(res.Body))

	type Result struct {
		Errcode int    `json:"errcode"`
		Errmsg  string `json:"errmsg"`
	}

	var result Result
	if err := json.Unmarshal(res.Body, &result); err != nil {
		slog.Error(err.Error())
		return err
	}
	if result.Errcode != 0 {
		return errors.New("编辑企业标签，返回结果：" + string(res.Body))
	}
	return nil
}

// DelCorpTag 删除企业标签
func (w *QYWXApi) DelCorpTag(tagId string, agentId int64) error {
	accessToken, err := w.GetAccessToken()
	if err != nil {
		return err
	}

	var values = url.Values{}
	values.Add("access_token", accessToken)
	reqUrl := "https://qyapi.weixin.qq.com/cgi-bin/externalcontact/del_corp_tag?" + values.Encode()

	var param = map[string]any{
		"tag_id":  tagId,
		"agentid": agentId,
	}
	data, _ := json.Marshal(param)

	res, err := w.getHttpSvc().HttpPost(reqUrl, nil, data)
	if err != nil {
		slog.Error(err.Error())
		return err
	}

	// 调试日志
	slog.Debug("DelCorpTag", "response", string(res.Body))

	type Result struct {
		Errcode int    `json:"errcode"`
		Errmsg  string `json:"errmsg"`
	}

	var result Result
	if err := json.Unmarshal(res.Body, &result); err != nil {
		slog.Error(err.Error())
		return err
	}
	if result.Errcode != 0 {
		return errors.New("删除企业标签，返回结果：" + string(res.Body))
	}
	return nil
}
